/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#pragma once

class TaskData
{
public:
	TaskData(WindowData *representative);
	
	void getWindows(vector<WindowData*> &outWindows);
	void getWindows(VirtualDesktop *desk, vector<WindowData*> &outWindows);
	void getDesks(vector<VirtualDesktop*> &outDesks);
	WindowData *getRepresentativeWindow();
	HICON getIcon(VirtualDesktop *desk, int size);
	bool containsWindow(WindowData *window);
	
private:
	friend class WindowTracker;
	
	void addWindow(WindowData *window);
	void removeWindow(WindowData *window);
	
	WindowData *representative;
	vector<WindowData*> children;
	
	TaskData *next;
	TaskData *prev;
};


class WindowTracker
{
public:
	WindowTracker();
	~WindowTracker();
	
	void save(std::ostream &stream);
	void restore(std::istream &stream);
	
	void windowCreated(HWND handle);
	void updateWindow(WindowData *window);
	void windowDestroyed(HWND handle);
	void windowActivated(HWND handle);
	bool update();
	void updateFocus();
	
	bool checkForChange();
	void updateMinimap(int desk);
	int getMinimapChangeIndex(int desk);
	
	TaskData *getFirstTask();
	TaskData *getLastTask();
	WindowData *getForegroundWindow();
	TaskData *getForegroundTask();
	void raiseLocalForeground();
	void getTasks(VirtualDesktop *desk, vector<TaskData*> &outTasks);
	void getWindows(VirtualDesktop *desk, vector<WindowData*> &outWindows);
	WindowData *getWindow(HWND window);
	bool deskIsEmpty(VirtualDesktop *desk);
	
	void reorderTask(TaskData *task, TaskData *prev, TaskData *next);
	
	HWND lastFocus;
	
private:
	
	static BOOL CALLBACK WindowTracker::windowChildListBuilder(HWND window, LPARAM param);
	static BOOL CALLBACK WindowTracker::windowListBuilder(HWND window, LPARAM param);
	bool shouldIgnoreWindow(HWND window);
	
	void updateWindowTask(WindowData *window);
	void removeTask(TaskData *task);
	void removeWindowFromTask(WindowData *window);
	WindowData *findParentTaskWindow(WindowData *window);
	
	TaskData *firstTask;
	TaskData *lastTask;
	multimap<DWORD, TaskData*> tasksByPid;
	
	set<WindowData*> unownedWindows;
	map<HWND, WindowData*> windows;
	vector<HWND> zOrder;
	WindowData *foreground;
	bool changed;
	
	vector<int> minimapChangeIndices;
	map<HWND, WindowData*> closedWindows;
};

extern WindowTracker *windowTracker;
